package com.acdc.config.service.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.acdc.config.domain.ElectricityExecTime;
import com.acdc.config.mapper.ElectricityConfigMapper;
import com.acdc.config.domain.ElectricityConfig;
import com.acdc.config.service.IElectricityConfigService;
import com.ruoyi.system.service.ISysDictDataService;

/**
 * 电价配置Service业务层处理
 * 
 * @author acdc
 * @date 2025-05-20
 */
@Service
public class ElectricityConfigServiceImpl implements IElectricityConfigService 
{
    @Autowired
    private ElectricityConfigMapper electricityConfigMapper;

    @Autowired
    private ISysDictDataService sysDictDataService;

    /**
     * 查询电价配置
     * 
     * @param id 电价配置主键
     * @return 电价配置
     */
    @Override
    public ElectricityConfig selectElectricityConfigById(Long id)
    {
        return electricityConfigMapper.selectElectricityConfigById(id);
    }

    /**
     * 查询电价配置列表
     * 
     * @param electricityConfig 电价配置
     * @return 电价配置
     */
    @Override
    public List<ElectricityConfig> selectElectricityConfigList(ElectricityConfig electricityConfig)
    {
        return electricityConfigMapper.selectElectricityConfigList(electricityConfig);
    }

    /**
     * 新增电价配置
     * 
     * @param electricityConfig 电价配置
     * @return 结果
     */
    @Transactional
    @Override
    public int insertElectricityConfig(ElectricityConfig electricityConfig)
    {
        int rows = electricityConfigMapper.insertElectricityConfig(electricityConfig);
        insertElectricityExecTime(electricityConfig);
        return rows;
    }

    /**
     * 修改电价配置
     * 
     * @param electricityConfig 电价配置
     * @return 结果
     */
    @Transactional
    @Override
    public int updateElectricityConfig(ElectricityConfig electricityConfig)
    {
        electricityConfigMapper.deleteElectricityExecTimeByConfigId(electricityConfig.getId());
        insertElectricityExecTime(electricityConfig);
        return electricityConfigMapper.updateElectricityConfig(electricityConfig);
    }

    /**
     * 批量删除电价配置
     * 
     * @param ids 需要删除的电价配置主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteElectricityConfigByIds(Long[] ids)
    {
        electricityConfigMapper.deleteElectricityExecTimeByConfigIds(ids);
        return electricityConfigMapper.deleteElectricityConfigByIds(ids);
    }

    /**
     * 删除电价配置信息
     * 
     * @param id 电价配置主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteElectricityConfigById(Long id)
    {
        electricityConfigMapper.deleteElectricityExecTimeByConfigId(id);
        return electricityConfigMapper.deleteElectricityConfigById(id);
    }

    /**
     * 新增电价执行时间段信息
     * 
     * @param electricityConfig 电价配置对象
     */
    public void insertElectricityExecTime(ElectricityConfig electricityConfig)
    {
        List<ElectricityExecTime> electricityExecTimeList = electricityConfig.getElectricityExecTimeList();
        Long id = electricityConfig.getId();
        if (StringUtils.isNotNull(electricityExecTimeList))
        {
            List<ElectricityExecTime> list = new ArrayList<ElectricityExecTime>();
            for (ElectricityExecTime electricityExecTime : electricityExecTimeList)
            {
                electricityExecTime.setConfigId(id);
                list.add(electricityExecTime);
            }
            if (list.size() > 0)
            {
                electricityConfigMapper.batchElectricityExecTime(list);
            }
        }
    }

    @Override
    public Float getElectricityPrice(Long configId)
    {
        ElectricityConfig electricityConfig = electricityConfigMapper.selectElectricityConfigById(configId);
        if (electricityConfig == null)
        {
            throw new RuntimeException("电价配置不存在");
        }
        // 获取当前时间
        Date now = new Date();
        String execDate = sysDictDataService.selectDictLabel("exec_date", electricityConfig.getExecDate());
        if (execDate == null)
        {
            throw new RuntimeException("电价执行日期不存在");
        }
        
        // 验证当前日期是否在执行日期范围内
        if (!isDateInExecRange(execDate, now)) {
            throw new RuntimeException("当前日期不在电价执行日期范围内：" + execDate);
        }

        List<ElectricityExecTime> electricityExecTimeList = electricityConfig.getElectricityExecTimeList();
        if (electricityExecTimeList == null || electricityExecTimeList.isEmpty())
        {
            throw new RuntimeException("电价执行时间段不存在");
        }
        
        // 遍历电价执行时间段，判断当前时间是否在时间段内
        for (ElectricityExecTime electricityExecTime : electricityExecTimeList)
        {
            String execTime = sysDictDataService.selectDictLabel("exec_time", electricityExecTime.getTimePeriodCode());
            if (execTime == null) {
                continue; // 跳过无效的时间段编码
            }
            
            // 判断当前时间是否在该时间段内
            if (isTimeInPeriod(execTime, now)) {
                return electricityExecTime.getPrice(); // 返回对应时间段的电价
            }
        }
        
        // 如果没有找到匹配的时间段，抛出异常
        throw new RuntimeException("当前时间不在任何电价执行时间段内");
    }

    /**
     * 判断当前日期是否在执行日期范围内
     * 支持格式：
     * 1. "9月至11月" - 月份范围
     * 2. "09/01至11/30" - 月日范围
     * 3. "尖峰/非尖峰日期（月日）01/01至12/31" - 复杂格式
     * 
     * @param execDate 执行日期字符串
     * @param currentDate 当前日期
     * @return true-在范围内，false-不在范围内
     */
    private boolean isDateInExecRange(String execDate, Date currentDate) {
        try {
            // 处理复杂格式，提取日期部分
            if (execDate.contains("（月日）")) {
                String[] parts = execDate.split("（月日）");
                if (parts.length == 2) {
                    execDate = parts[1]; // 提取日期部分
                }
            }
            
            // 分割开始和结束日期
            if (!execDate.contains("至")) {
                throw new RuntimeException("执行日期格式错误，缺少'至'分隔符：" + execDate);
            }
            
            String[] execDateArr = execDate.split("至");
            if (execDateArr.length != 2) {
                throw new RuntimeException("执行日期格式错误，无法解析开始和结束日期：" + execDate);
            }
            
            String startDate = execDateArr[0].trim();
            String endDate = execDateArr[1].trim();
            
            // 判断是否为月日格式 (MM/DD)
            if (startDate.contains("/") && endDate.contains("/")) {
                return isDateInMonthDayRange(startDate, endDate, currentDate);
            }
            // 判断是否为月份格式 (X月)
            else if (startDate.contains("月") && endDate.contains("月")) {
                return isDateInMonthRange(startDate, endDate, currentDate);
            }
            else {
                throw new RuntimeException("不支持的执行日期格式：" + execDate);
            }
            
        } catch (Exception e) {
            throw new RuntimeException("解析执行日期时发生错误：" + e.getMessage(), e);
        }
    }
    
    /**
     * 判断当前日期是否在月日范围内 (MM/DD格式)
     */
    private boolean isDateInMonthDayRange(String startDate, String endDate, Date currentDate) {
        try {
            // 解析开始日期
            String[] startParts = startDate.split("/");
            if (startParts.length != 2) {
                throw new RuntimeException("开始日期格式错误：" + startDate);
            }
            int startMonth = Integer.parseInt(startParts[0]);
            int startDay = Integer.parseInt(startParts[1]);
            
            // 解析结束日期
            String[] endParts = endDate.split("/");
            if (endParts.length != 2) {
                throw new RuntimeException("结束日期格式错误：" + endDate);
            }
            int endMonth = Integer.parseInt(endParts[0]);
            int endDay = Integer.parseInt(endParts[1]);
            
            // 验证日期有效性
            if (!isValidMonthDay(startMonth, startDay) || !isValidMonthDay(endMonth, endDay)) {
                throw new RuntimeException("日期格式无效，月份应在1-12之间，日期应在1-31之间");
            }
            
            // 获取当前月日
            int currentMonth = currentDate.getMonth() + 1; // Date.getMonth() 返回 0-11
            int currentDay = currentDate.getDate();
            
            // 处理跨年的情况（如 11/01 至 02/28）
            if (startMonth > endMonth) {
                // 跨年情况：当前日期在 startMonth 之后 或 在 endMonth 之前
                return (currentMonth > startMonth || (currentMonth == startMonth && currentDay >= startDay)) ||
                       (currentMonth < endMonth || (currentMonth == endMonth && currentDay <= endDay));
            } else {
                // 同一年内：当前日期在范围内
                if (currentMonth < startMonth || currentMonth > endMonth) {
                    return false;
                }
                if (currentMonth == startMonth && currentDay < startDay) {
                    return false;
                }
                if (currentMonth == endMonth && currentDay > endDay) {
                    return false;
                }
                return true;
            }
            
        } catch (NumberFormatException e) {
            throw new RuntimeException("日期格式错误，无法解析数字：" + e.getMessage());
        }
    }
    
    /**
     * 判断当前日期是否在月份范围内 (X月格式)
     */
    private boolean isDateInMonthRange(String startDate, String endDate, Date currentDate) {
        try {
            // 解析开始月份
            String startMonthStr = startDate.replace("月", "").trim();
            int startMonth = Integer.parseInt(startMonthStr);
            
            // 解析结束月份
            String endMonthStr = endDate.replace("月", "").trim();
            int endMonth = Integer.parseInt(endMonthStr);
            
            // 验证月份有效性
            if (startMonth < 1 || startMonth > 12 || endMonth < 1 || endMonth > 12) {
                throw new RuntimeException("月份格式无效，应在1-12之间");
            }
            
            // 获取当前月份
            int currentMonth = currentDate.getMonth() + 1; // Date.getMonth() 返回 0-11
            
            // 处理跨年的情况（如 11月至2月）
            if (startMonth > endMonth) {
                // 跨年情况：当前月份在 startMonth 之后 或 在 endMonth 之前
                return currentMonth >= startMonth || currentMonth <= endMonth;
            } else {
                // 同一年内：当前月份在范围内
                return currentMonth >= startMonth && currentMonth <= endMonth;
            }
            
        } catch (NumberFormatException e) {
            throw new RuntimeException("月份格式错误，无法解析数字：" + e.getMessage());
        }
    }
    
    /**
     * 验证月日格式是否有效
     */
    private boolean isValidMonthDay(int month, int day) {
        if (month < 1 || month > 12) {
            return false;
        }
        
        // 简单验证日期范围（实际项目中可以使用更精确的验证）
        if (day < 1 || day > 31) {
            return false;
        }
        
        // 特殊月份日期验证
        if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) {
            return false;
        }
        
        if (month == 2 && day > 29) {
            return false;
        }
        
        return true;
    }

    /**
     * 判断当前时间是否在指定的时间段内
     * 支持格式：
     * 1. "谷段(20:00-24:00)" - 带描述的时间范围
     * 2. "尖段(时:分:秒) 00:00:00-09:59:59" - 带描述和秒级精度的时间范围
     * 3. "峰段15:00-20:00" - 带描述的时间范围
     * 4. "20:00-24:00" - 纯时间范围
     * 
     * @param execTime 执行时间字符串
     * @param currentDate 当前时间
     * @return true-在时间段内，false-不在时间段内
     */
    private boolean isTimeInPeriod(String execTime, Date currentDate) {
        try {
            // 提取时间范围部分
            String timeRange = extractTimeRange(execTime);
            if (timeRange == null) {
                return false;
            }
            
            // 解析时间范围
            TimeRange range = parseTimeRange(timeRange);
            if (range == null) {
                return false;
            }
            
            // 获取当前时间的小时、分钟、秒
            int currentHour = currentDate.getHours();
            int currentMinute = currentDate.getMinutes();
            int currentSecond = currentDate.getSeconds();
            
            // 将当前时间转换为秒数，便于比较
            int currentTimeInSeconds = currentHour * 3600 + currentMinute * 60 + currentSecond;
            
            // 判断当前时间是否在范围内
            return isTimeInRange(range, currentTimeInSeconds);
            
        } catch (Exception e) {
            // 记录日志但不抛出异常，避免影响其他时间段的判断
            System.err.println("解析时间段时发生错误：" + execTime + ", 错误：" + e.getMessage());
            return false;
        }
    }
    
    /**
     * 从执行时间字符串中提取时间范围
     */
    private String extractTimeRange(String execTime) {
        if (execTime == null || execTime.trim().isEmpty()) {
            return null;
        }
        
        // 查找时间范围模式：HH:MM-HH:MM 或 HH:MM:SS-HH:MM:SS
        String timePattern = "\\d{1,2}:\\d{2}(:\\d{2})?-\\d{1,2}:\\d{2}(:\\d{2})?";
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(timePattern);
        java.util.regex.Matcher matcher = pattern.matcher(execTime);
        
        if (matcher.find()) {
            return matcher.group();
        }
        
        return null;
    }
    
    /**
     * 解析时间范围字符串
     */
    private TimeRange parseTimeRange(String timeRange) {
        if (timeRange == null || !timeRange.contains("-")) {
            return null;
        }
        
        String[] parts = timeRange.split("-");
        if (parts.length != 2) {
            return null;
        }
        
        String startTime = parts[0].trim();
        String endTime = parts[1].trim();
        
        TimeRange range = new TimeRange();
        range.startTime = parseTimeToSeconds(startTime);
        range.endTime = parseTimeToSeconds(endTime);
        
        return range;
    }
    
    /**
     * 将时间字符串转换为秒数
     */
    private int parseTimeToSeconds(String timeStr) {
        String[] parts = timeStr.split(":");
        if (parts.length < 2 || parts.length > 3) {
            return -1;
        }
        
        int hour = Integer.parseInt(parts[0]);
        int minute = Integer.parseInt(parts[1]);
        int second = parts.length == 3 ? Integer.parseInt(parts[2]) : 0;
        
        // 验证时间有效性，需要考虑24:00

        if (hour < 0 || hour > 24 || minute < 0 || minute > 59 || second < 0 || second > 59) {
            return -1;
        }
        
        return hour * 3600 + minute * 60 + second;
    }
    
    /**
     * 判断当前时间是否在时间范围内
     */
    private boolean isTimeInRange(TimeRange range, int currentTimeInSeconds) {
        if (range.startTime == -1 || range.endTime == -1) {
            return false;
        }
        
        // 处理跨天的情况（如 23:00-01:00）
        if (range.startTime > range.endTime) {
            // 跨天情况：当前时间在 startTime 之后 或 在 endTime 之前
            return currentTimeInSeconds >= range.startTime || currentTimeInSeconds <= range.endTime;
        } else {
            // 同一天内：当前时间在范围内
            return currentTimeInSeconds >= range.startTime && currentTimeInSeconds <= range.endTime;
        }
    }
    
    /**
     * 时间范围内部类
     */
    private static class TimeRange {
        int startTime; // 开始时间（秒数）
        int endTime;   // 结束时间（秒数）
    }
}
